from typing import Iterable
from PyQt6.QtCore import Qt
from PyQt6.QtGui import QResizeEvent
from PyQt6.QtWidgets import QDockWidget
from GUI.New_start import Ui_Start
from GUI.MainWindow import Ui_MainWindow
from GUI.MyWorkSpace import MyWorkSpace
from GUI.FirstStep import Ui_FirstStep
from GUI.SecondStep import Ui_SecondStep
from GUI.ThirdStep import Ui_ThirdStep
from Utils.image_precesser import Graph, GRID, image_LOD
from PyQt6.QtWidgets import * 
from PyQt6.QtGui import *
from PyQt6.QtCore import *
import multiprocessing
        
class FirstStep(QDialog, Ui_FirstStep):
    openSecondStep = pyqtSignal(str)
    def __init__(self, reciever):
        super(FirstStep, self).__init__()
        self.setupUi(self)
        self.open.clicked.connect(self.open_file)
        self.next_step.clicked.connect(self.next_step_clicked)
        self.openSecondStep.connect(reciever.open_second_step)
        self.file_path = None

    def open_file(self):
        file_dialog = QFileDialog(self)
        file_dialog.setFileMode(QFileDialog.FileMode.ExistingFiles)
        if file_dialog.exec():
            self.file_path = file_dialog.selectedFiles()[0]
            self.lineEdit.setText(self.file_path)

    def next_step_clicked(self):
        if self.file_path:
            self.close()
            self.openSecondStep.emit(self.file_path)
        else:
            QMessageBox.information(self, "提示", "请选择文件", QMessageBox.StandardButton.Ok)

class SecondStep(QDialog, Ui_SecondStep):
    openFirstStep = pyqtSignal()
    openThirdStep = pyqtSignal(str, int, int)
    def __init__(self, reciever, image_path):
        super(SecondStep, self).__init__()
        self.setupUi(self)
        self.last_step.clicked.connect(self.last_step_clicked)
        self.next_step.clicked.connect(self.next_step_clicked)
        self.openFirstStep.connect(reciever.open_first_step)
        self.openThirdStep.connect(reciever.open_third_step)
        self.spinBox.valueChanged.connect(self.change_label)
        self.spinBox_2.valueChanged.connect(self.change_label)
        self.image_path = image_path
        image_reader = QImageReader(image_path)
        if not image_reader.canRead():
            print("Unable to read image file.")
            return None
        self.width = image_reader.size().width()
        self.height = image_reader.size().height()
        self.display(self.width, self.height)

        import math
        width_split = math.log2(self.height // 1000)
        height_split = math.log2(self.width // 1000)
        self.spinBox.setValue(int(width_split))
        self.spinBox_2.setValue(int(height_split))
        self.change_label()

    def display(self, width, height):
        label = f"图片大小：{height}x{width}"
        self.label.setText(label)

    def change_label(self):
        width_split = self.spinBox.value()
        height_split = self.spinBox_2.value()
        label = f"切分大小：{int(self.height // (2 ** width_split))}x{int(self.width // (2 ** height_split))}"
        self.label_2.setText(label)
        

    def open_file(self):
        file_dialog = QFileDialog(self)
        file_dialog.setFileMode(QFileDialog.FileMode.ExistingFiles)
        if file_dialog.exec():
            self.file_path = file_dialog.selectedFiles()[0]
            self.lineEdit.setText(self.file_path)

    def next_step_clicked(self):
        width_split = self.spinBox.value()
        height_split = self.spinBox_2.value()
        self.close()
        self.openThirdStep.emit(self.image_path, width_split, height_split)

    def last_step_clicked(self):
        self.close()
        self.openFirstStep.emit()

class ThirdStep(QDialog, Ui_ThirdStep):
    openSecondStep = pyqtSignal(str)
    over = pyqtSignal(str, str, int, int, int)
    def __init__(self, reciever, image_path, width_split, height_split):
        super(ThirdStep, self).__init__()
        self.setupUi(self)
        self.image_path = image_path
        self.width_split = width_split
        self.height_split = height_split
        self.output_path = None
        self.open.clicked.connect(self.save)
        self.finish.clicked.connect(self.finish_clicked)
        self.over.connect(reciever.create_project)
        self.last_step.clicked.connect(self.last_step_clicked)
        self.openSecondStep.connect(reciever.open_second_step)

    def save(self):
        import shutil
        import os
        import sys
        # 保存文件对话框
        fname,_=QFileDialog.getSaveFileName(self,'项目保存地址',f"./{self.image_path.split('/')[-1].split('.')[0]}", options=QFileDialog.Option.ShowDirsOnly)
        if fname:
            if os.path.exists(fname):
               shutil.rmtree(fname) 
            os.makedirs(fname)
            self.output_path = fname
            self.lineEdit.setText(fname)
    
    def finish_clicked(self):
        if self.output_path:
            self.close()
            scale_rate = min(1, min(self.width_split, self.height_split))
            self.over.emit(self.image_path, self.output_path, self.width_split, self.height_split, scale_rate)
        else:
            QMessageBox.information(self, "提示", "请选择保存路径", QMessageBox.StandardButton.Ok)

    def last_step_clicked(self):
        self.close()
        self.openSecondStep.emit(self.image_path)

class WorkerThread(QThread):
    progress_updated = pyqtSignal(str,int)
    def __init__(self,image_path, output_path, width_split, height_split):
        super().__init__()
        self.image_path = image_path
        self.output_path = output_path
        self.width_split = width_split
        self.height_split = height_split
    
    def run(self):
        image_LOD(self.image_path, self.output_path, 2 ** self.width_split, 2 ** self.height_split, self.progress_updated)

    

    


class ProgressBar(QDialog):
    def __init__(self,parent=None):
        super(ProgressBar, self).__init__(parent)
 
        # Qdialog窗体的设置
        self.resize(300, 32) # QDialog窗的大小
 
        # 创建并设置 QProcessbar
        self.progressBar = QProgressBar(self) # 创建
        self.progressBar.setMinimum(0) #设置进度条最小值
        self.progressBar.setMaximum(100)  # 设置进度条最大值
        self.progressBar.setValue(0)  # 进度条初始值为0
        self.progressBar.setGeometry(QRect(5, 3, 295, 28)) # 设置进度条在 QDialog 中的位置 [左，上，右，下]
        # 禁止关闭
        self.setWindowFlag(Qt.WindowType.WindowCloseButtonHint, False)
        # 禁止拉伸
        self.setFixedSize(300, 32)


    def setValue(self,label, value): # 设置总任务进度和子任务进度
        print(label, value)
        self.setWindowTitle(self.tr(label)) # 顶部的标题
        self.progressBar.setValue(int(value))


    

class MyMainWindow(QMainWindow, Ui_MainWindow):
    def __init__(self):
        super(MyMainWindow, self).__init__()
        self.setupUi(self)
        self.setWindowTitle("病理切片标注系统")
        self.setWindowIcon(QIcon(":/tools/icon.ico"))
        self.start = QWidget(self)
        # self.setGeometry(800, 300, 800, 600)
        self.start.setGeometry(200, 100, 400, 300)
        self.start_ui = Ui_Start()
        self.start_ui.setupUi(self.start)
        self.start_ui.open_project.clicked.connect(self.open_project)
        self.start_ui.create_project.clicked.connect(self.open_first_step)
        # workspace
        self.workspace = None
    
    def resizeEvent(self, a0: QResizeEvent) -> None:
        new_size = a0.size()
        x = new_size.width() // 2 - 200
        y = new_size.height() // 2 - 150
        self.start.setGeometry(x, y, 400, 300)

    def open_project(self):
        file_dialog = QFileDialog(self)
        # 选择文件夹
        file_dialog.setFileMode(QFileDialog.FileMode.Directory)
        if file_dialog.exec():
            file_path = file_dialog.selectedFiles()[0]
            self.output_path = file_path
            try:
                graph = Graph(file_path)
                
            except Exception as e:
                # 对话框
                QMessageBox.information(self, "提示", "不合法的项目", QMessageBox.StandardButton.Ok)
                return
            
            self.workspace = MyWorkSpace(file_path, self)
            self.setWindowTitle(f"病理切片标注系统 - {file_path}")
            self.setCentralWidget(self.workspace)
    
    def open_first_step(self):
        self.first_step = FirstStep(self)
        self.first_step.exec()

    def open_second_step(self, file_path):
        self.second_step = SecondStep(self, file_path)
        self.second_step.exec()

    def open_third_step(self, image_path, width_split, height_split):
        self.third_step = ThirdStep(self, image_path, width_split, height_split)
        self.third_step.exec()

    def create_project(self, image_path, output_path, width_split, height_split, scale_rate):
        self.output_path = output_path
        self.process_bar = ProgressBar()
        self.process_bar.show()
        # 在output_path下创建一个metadata.json
        import os, json
        with open(os.path.join(output_path, "metadata.json"), "w") as f:
            f.write(json.dumps({
                "save_scale_rate": scale_rate
            }))
        # 主页面禁止
        self.start.setEnabled(False)
        self.thread = WorkerThread(image_path, output_path, width_split, height_split)
        self.thread.progress_updated.connect(self.update_progress_bar)
        self.thread.start()
    
    def update_progress_bar(self, label, value):
        self.process_bar.setValue(label, value)
        if value == 100:
            self.process_bar.close()
            QMessageBox.information(self, "提示", "处理完成", QMessageBox.StandardButton.Ok)
            self.process_bar = None
            self.thread = None
            self.workspace = MyWorkSpace(self.output_path, self)
            self.workspace.init_layers()
            self.setWindowTitle(f"病理切片标注系统 - {self.output_path}")
            self.setCentralWidget(self.workspace)
    
    def unsaved_warning(self, flag: bool):
        if flag:
            self.setWindowTitle(f"病理切片标注系统 - {self.output_path}")
        else:
            self.setWindowTitle(f"病理切片标注系统 - {self.output_path} *")

    def back_to_start(self):
        # self.setCentralWidget(self.start)
        self.start.setEnabled(True)
        x = self.geometry().width() // 2 - 200
        y = self.geometry().height() // 2 - 150
        self.start.setGeometry(x, y, 400, 300)
        self.workspace.close()
        self.setWindowTitle("病理切片标注系统")

    def closeEvent(self, event):
        # 在父 Widget 关闭时，先尝试关闭子 Widget
        if self.workspace:
            if self.windowTitle().endswith("*"):
                reply = QMessageBox.question(self, '提示', '是否保存项目', QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No | QMessageBox.StandardButton.Cancel)
                if reply == QMessageBox.StandardButton.Yes:
                    self.workspace.save()
                elif reply == QMessageBox.StandardButton.Cancel:
                    event.ignore()
                    return
            self.workspace.close()
        super().closeEvent(event)